﻿#define _CRT_SECURE_NO_WARNINGS
#include"Date.h"

Date::Date(int year, int month, int day)//缺省值在声明中给出
{
	_year = year;
	_month = month;
	_day = day;
	if (!Daycheck())
	{
		cout << "非法输入日期->" << *this;
	}
}

void Date::Print() const
{
	cout << _year << '/' << _month << '/' << _day << endl;
}

bool Date::Daycheck()
{
	if (_month >= 1 && _month <= 12 && _day >= 1 && _day <= GetMonthDay(_year, _month))
	{
		return true;
	}
	else
	{
		return false;
	}
}

//---------------------------------------------------------------------

bool Date::operator==(const Date& a) const//如果⼀个重载运算符函数是成员函数，则它的第⼀个运算对象默认传给隐式的this指针，因此运算符重载作为成员函数时，参数⽐运算对象少⼀个。
{
	return _year == a._year
		&& _month == a._month
		&& _day == a._day;
}

bool Date::operator!=(const Date& a) const
{
	return !(*this == a);
}

//判断大小 <
bool Date::operator<(const Date& d) const
{
	if (_year != d._year) return _year < d._year;
	if (_month != d._month) return _month < d._month;
	return _day < d._day;
}
//判断大小 <=
bool Date::operator<=(const Date& a) const
{
	return (*this < a) || (*this == a);
}

//判断大小 >
bool Date::operator>(const Date& a) const
{
	return !(*this <= a);
	//if (_year != d._year) return _year > d._year;
	//if (_month != d._month) return _month > d._month;
	//return _day > d._day;
}
//判断大小 >=
bool Date::operator>=(const Date& a) const
{
	//return (*this > a) || (*this == a);
	return !(*this < a);
}

//---------------------------------------------------------------------

Date& Date::operator+=(int day)//这些会改变对象的不能在后面加const
{
	if (day < 0)
	{
		return *this -= (-day);
	}
	_day += day;
	while (_day > GetMonthDay(_year, _month))
	{
		_day -= GetMonthDay(_year, _month);
		_month++;
		if (_month == 13)
		{
			_year++;
			_month = 1;
		}
	}
	return *this;
}

//Date Date::operator+(int day)
//{
//	Date temp = *this;
//	temp._day += day;
//	while (temp._day > GetMonthDay(temp._year, temp._month))
//	{
//		temp._day -= GetMonthDay(temp._year, temp._month);
//		temp._month++;
//		if (temp._month == 13)
//		{
//			temp._year++;
//			temp._month = 1;
//		}
//	}
//	return temp;
//}

Date Date::operator+(int day) const//也可以这样写  (+= + 代码很多类似的所以原来的 + 可以改进)
{
	Date temp = *this;
	temp += day;//temp.operator+=(day);
	return temp;
}

//---------------------------------------------------------------------
// 会改变传入的对象
// 日期-天数
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		return *this += (-day);
	}
	_day -= day;
	while (_day <= 0)
	{
		_month--;
		if (_month == 0)
		{
			_year--;
			_month = 12;
		}
		_day += GetMonthDay(_year,_month);
	}
	return *this;
}

// 日期-天数
Date Date::operator-(int day) const
{
	Date temp = *this;
	temp -= day;
	return temp;
}

//// 日期-天数
//Date Date::operator-(int day) //也可以这样写，但是这样写没有上面的好，因为这里的拷贝调用特别多
//{
//	Date temp = *this;
//	temp._day -= day;
//	while (temp._day <= 0)
//	{
//		temp._month--;
//		if (temp._month == 0)
//		{
//			temp._year--;
//			temp._month = 12;
//		}
//		temp._day += GetMonthDay(temp._year, temp._month);
//	}
//	return temp;
//}
//
//Date& Date::operator-=(int day)
//{
//	*this = *this - day;
//	return *this;
//}

//---------------------------------------------------------------------

// ++d1; -> d1.operatpr++();
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
// d1++; -> d1.operatpr++(1);
Date Date::operator++(int)//后置++
{
	Date temp(*this);//拷贝构造,自己复制了一份，不是原来的空间。与后置思想一样
	*this += 1;
	return temp;
}

// --d1; -> d1.operatpr--();
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
// d1--; -> d1.operatpr--(1);
Date Date::operator--(int)
{
	Date temp(*this);//拷贝构造
	*this -= 1;
	return temp;
}

//---------------------------------------------------------------------
// 日期差值
int Date::operator-(const Date& d) const
{
	Date earlier = *this < d ? *this : d;
	Date later = *this < d ? d : *this;

	int days = 0;
	while (earlier < later) {
		++earlier;
		++days;
	}
	return *this < d ? -days : days;
}
//---------------------------------------------------------------------

ostream& operator<<(ostream& out, const Date& d1)
{
	out << d1._year << "年" << d1._month << "月" << d1._day << "日" << endl;
	return out;//为了让使用不变成d1<<cout (d1.operator<<(cout);显式调用)  解决办法就是重载为全局函数
}

istream& operator>>(istream& in, Date& d)
{
	while (1) {
		cout << "请依次输入年月日:>";
		in >> d._year >> d._month >> d._day;
		if (d.Daycheck())
		{
			break;
		}
		else
		{
			cout << "非法日期，请重新输入!" << endl;
		}
	}
	return in;
}